package me.zhengjie.modules.system.service.impl;

import lombok.RequiredArgsConstructor;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.Requirement;
import me.zhengjie.modules.system.domain.System;
import me.zhengjie.modules.system.repository.RequirementRepository;
import me.zhengjie.modules.system.repository.SystemRepository;
import me.zhengjie.modules.system.service.RequirementService;
import me.zhengjie.modules.system.service.dto.RequirementDto;
import me.zhengjie.modules.system.service.dto.SystemDto;
import me.zhengjie.modules.system.service.mapstruct.RequirementMapper;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.StringUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * RequirementServiceImpl
 *
 * @author guoyuan
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "requirement")
public class RequirementServiceImpl implements RequirementService {

    private final RequirementRepository requirementRepository;
    private final SystemRepository systemRepository;
    private final RequirementMapper requirementMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Requirement resources, String systemId) {
        final Optional<System> byId = systemRepository.findById(systemId);
        if (!byId.isPresent()) {
            throw new BadRequestException("已选系统不存在");
        }
        resources.setRequirementId(getRequirementId());
        resources.setSystem(byId.get());
        requirementRepository.save(resources);
    }

    private int getRequirementId() {
        final Requirement first = requirementRepository.findFirstByOrderByRequirementIdDesc();
        int systemId;
        if (first == null) {
            systemId = 1;
        } else {
            systemId = first.getRequirementId() + 1;
        }
        return systemId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<String> ids) {
        final List<Requirement> allById = requirementRepository.findAllByIdInOrderByRequirementIdAsc(ids);
        if (allById.isEmpty()) {
            return;
        }
        final Requirement first = allById.get(0);
        final Integer requirementId = first.getRequirementId();
        final Map<String, Requirement> collect = requirementRepository.findAllByRequirementIdGreaterThanOrderByRequirementIdAsc(requirementId)
                .stream().collect(Collectors.toMap(Requirement::getId, s -> s));
        for (Requirement delete : allById) {
            collect.remove(delete.getId());
            requirementRepository.delete(delete);
        }
        final List<Requirement> requirementList = new ArrayList<>(collect.values());
        if (!requirementList.isEmpty()) {
            final Requirement lastRequirement = requirementRepository.findFirstByRequirementIdLessThanOrderByRequirementIdDesc(requirementId);
            Integer lastRequirementId = 0;
            if (lastRequirement != null) {
                lastRequirementId = lastRequirement.getRequirementId();
            }
            for (Requirement requirement : requirementList) {
                lastRequirementId += 1;
                requirement.setRequirementId(lastRequirementId);
            }
            requirementRepository.saveAll(requirementList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(RequirementDto resources) {
        final String id = resources.getId();
        if (StringUtils.isBlank(id)) {
            throw new BadRequestException("需求id不能为空");
        }
        final Optional<Requirement> requirementById = requirementRepository.findById(id);
        if (!requirementById.isPresent()) {
            throw new BadRequestException("需求[" + resources.getRequirementTheme() + "]不存在");
        }
        final SystemDto systemDto = resources.getSystem();
        if (systemDto == null) {
            throw new BadRequestException("系统不能为空");
        }
        final String systemDtoId = systemDto.getId();
        if (StringUtils.isBlank(systemDtoId)) {
            throw new BadRequestException("系统id不能为空");
        }
        final Optional<System> systemById = systemRepository.findById(systemDtoId);
        if (!systemById.isPresent()) {
            throw new BadRequestException("系统[" + systemDto.getSystemName() + "]不存在");
        }
        final Requirement requirement = requirementById.get();
        final Requirement entity = requirementMapper.toEntity(resources);
        entity.setRequirementId(requirement.getRequirementId());
        entity.setSystem(systemById.get());
        requirementRepository.save(entity);
    }

    @Override
    public Map<String, Object> queryAll(Pageable pageable) {
        // TODO: 临时强制指定分页参数sort
        final Page<Requirement> page = requirementRepository.findAll(PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(Sort.Direction.DESC, "requirementId")));
        return PageUtil.toPage(page.map(requirementMapper::toDto));
    }
}
